package com.yuanfeng.payment.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import com.jfinal.weixin.sdk.api.PaymentApi;
import com.yuanfeng.commoms.config.WXConfigUtil;
import com.yuanfeng.commoms.config.WXPayConfig;
import com.yuanfeng.commoms.config.YFConfig;
import com.yuanfeng.commoms.exception.BizCodeEnume;
import com.yuanfeng.commoms.util.ParseTokenUtils;
import com.yuanfeng.commoms.util.PayToolUtil;
import com.yuanfeng.commoms.util.RedisUtil;
import com.yuanfeng.commoms.util.ResponseResult;
import com.yuanfeng.commoms.vo.user.UserInfoVO;
import com.yuanfeng.payment.dto.GoodsDTO;
import com.yuanfeng.payment.feign.UsermsServiceClient;
import com.yuanfeng.payment.mapper.PayConfigMapper;
import com.yuanfeng.payment.mapper.PayConsumeRecordMapper;
import com.yuanfeng.payment.mapper.PayConsumeTradeBackMapper;
import com.yuanfeng.payment.mapper.PayConsumeTradeMapper;
import com.yuanfeng.payment.service.PayStrategyHandleService;
import com.yuanfeng.payment.vo.RecordVO;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Stranger
 * @date 2023/4/13 15:16
 */
@Service
public class WXPayAPPServicesImpl implements PayStrategyHandleService {


    private static PayConfigMapper payConfigMapper;


    private static PayConsumeTradeMapper payConsumeTradeMapper;


    private static PayConsumeTradeBackMapper payConsumeTradeBackMapper;


    private static PayConsumeRecordMapper payConsumeRecordMapper;


    private static UsermsServiceClient usermsServiceClient;

    // 注入的时候，给类的 service 注入
    @Autowired
    public void setUsermsServiceClient(UsermsServiceClient usermsServiceClient) {

        WXPayAPPServicesImpl.usermsServiceClient = usermsServiceClient;
    }

    // 注入的时候，给类的 service 注入
    @Autowired
    public void setMapper(PayConfigMapper payConfigMapper, PayConsumeTradeMapper payConsumeTradeMapper,
                          PayConsumeTradeBackMapper payConsumeTradeBackMapper, PayConsumeRecordMapper payConsumeRecordMapper) {
        WXPayAPPServicesImpl.payConfigMapper = payConfigMapper;
        WXPayAPPServicesImpl.payConsumeTradeMapper = payConsumeTradeMapper;
        WXPayAPPServicesImpl.payConsumeTradeBackMapper = payConsumeTradeBackMapper;
        WXPayAPPServicesImpl.payConsumeRecordMapper = payConsumeRecordMapper;
    }

    final static Logger log = LoggerFactory.getLogger(WXPayAPPServicesImpl.class);

    /**
     * 初始化 阿里云支付参数
     */
    public void initWXPayConfig() {
        //微信 pc  h5
        String paymentMode = "00";
        Map<String, Object> outMap = payConfigMapper.selectPayConfig(paymentMode);
        WXPayConfig.API_KEY = outMap.get("appAPIKey").toString();
        WXPayConfig.APP_SECRET = outMap.get("appSecret").toString();
        WXPayConfig.MCH_ID = outMap.get("appMCHId").toString();
        WXPayConfig.APP_ID = outMap.get("appID").toString();
        WXPayConfig.NOTIFY_URL = outMap.get("notifyUrl").toString();
        WXPayConfig.REDIRECT_URL = outMap.get("redirectUrl").toString();
        if(outMap.containsKey("weChatPcPath")){
            WXPayConfig.weChatWapPath=outMap.get("weChatPcPath").toString();
        }


        //微信app
        WXConfigUtil.KEY = outMap.get("appAPIKey").toString();
        WXConfigUtil.APP_SECRET = outMap.get("appSecret").toString();
        WXConfigUtil.MCH_ID = outMap.get("appMCHId").toString();
        WXConfigUtil.APP_ID = outMap.get("appID").toString();
        WXConfigUtil.NOTIFY_URL_APP = outMap.get("notifyUrl").toString();
        //微信小程序
        String paymentMode2 = "02";
        Map<String, Object> outMap2 = payConfigMapper.selectPayConfig(paymentMode2);
        WXPayConfig.Applet_APP_ID = outMap2.get("appID").toString();
        WXPayConfig.Applet_APP_SECRET = outMap2.get("appSecret").toString();

    }

    @Override
    public ResponseResult userPayEntrance(Map<Object, Object> map, HttpServletRequest request, HttpServletResponse response) {
        //查询支付配置信息
        this.initWXPayConfig();
        String outTradeNo = (String) map.get("orderId");
        String token = (String) map.get("token");
        BigDecimal totalPrice = new BigDecimal(0);
        // 来源
        Integer orderFromNum = map.get("platForm") == null ? 0 : Integer.parseInt(map.get("platForm").toString());
        // 订单来源存值
        RedisUtil.set(YFConfig.YF_ORDERFORM + outTradeNo, orderFromNum.toString(), 86400);

        // 处理自营店铺
        if (!StringUtils.isEmpty(RedisUtil.get(YFConfig.YF_ORDER_USER_TOKEN + outTradeNo))) {
            RedisUtil.remove(YFConfig.YF_ORDER_USER_TOKEN + outTradeNo);
        }
        RedisUtil.set(YFConfig.YF_ORDER_USER_TOKEN + outTradeNo, token, 86400);

        String goodsName = "订单编号" + outTradeNo;

        Integer amountAotalIntegral = null;
        //积分商品 0  是  1 否
        Integer integralGoods = 1;
        UserInfoVO ui = ParseTokenUtils.getUserInfoByToken(token);
        String userId = ui.getUserId();

        // 查询商品名与商品价格
        if (PayToolUtil.isInteger(outTradeNo)) {
            GoodsDTO queryGoodsPara = payConsumeTradeMapper.queryGoodsPriceAndName(outTradeNo);
            // 总价
            totalPrice = queryGoodsPara.getTradePaymentAmount();

            GoodsDTO queryGoodsPara2 = payConsumeTradeBackMapper.queryGoodsPriceAndName(outTradeNo, userId);
            //获取积分商品订单的积分
            Integer totalIntegral = queryGoodsPara2.getTotalIntegral();
            //积分商品 0  是  1 否
            integralGoods = queryGoodsPara2.getIntegralGoods();
            amountAotalIntegral = totalIntegral;
        } else {
            List<RecordVO> rp = payConsumeRecordMapper.queryRecordParaList(outTradeNo);
            for (RecordVO recordVO : rp) {
                BigDecimal price = recordVO.getRecordMoney();
                totalPrice = totalPrice.add(price);
            }
            // 获取积分商品的积分
            String totalIntegral = RedisUtil
                    .get(YFConfig.YF_USERINTEGRALYPAID + "--" + token + "--" + userId);
            if (null != totalIntegral) {
                //amountAotalIntegral 不为null 证明是积分订单
                amountAotalIntegral = Integer.valueOf(totalIntegral);
                //积分商品 0  是  1 否
                integralGoods = 0;
            }
        }
        if (null != integralGoods && integralGoods == 0) {
            //获取用户积分
            Integer userIntegral = usermsServiceClient.getMemberIntegralByUserId(userId);
            if (null != userIntegral && amountAotalIntegral > userIntegral) {
                //账户积分不足
                return ResponseResult.fail(BizCodeEnume.PAY_INTEGRAL_ERROR);
            }
        }
        Map<String, String> params = new HashMap<String, String>();
        String sign = null;
        Map<String, String> returnMap = new HashMap<>();
        try {
            WXConfigUtil config = new WXConfigUtil();

            String payAmount = String.valueOf(totalPrice);
            String price = PayToolUtil.getMoney(payAmount);

            params.put("appid", config.getAppID());
            params.put("mch_id", config.getMchID());
            params.put("nonce_str", PayToolUtil.create_nonce_str());
            params.put("body", goodsName);
            params.put("out_trade_no", outTradeNo);
            params.put("total_fee", price);

            params.put("spbill_create_ip", PayToolUtil.getIpAddr(request));
            params.put("notify_url", config.NOTIFY_URL_APP);
            params.put("trade_type", "APP");
            sign = WXPayUtil.generateSignature(params, config.getKey());;
            params.put("sign", sign);

            log.info("param{}", JSON.toJSONString(params));
            String xmlResult = PaymentApi.pushOrder(params);
            WXPay wxpay = new WXPay(config);
            //使用官方API请求预付订单
            Map<String, String> wxResponse = wxpay.unifiedOrder(params);
            //获取返回码
            String returnCode = wxResponse.get("return_code");
            //若返回码为SUCCESS，则会返回一个result_code,再对该result_code进行判断
            if (returnCode.equals("SUCCESS")) {
                //主要返回以下5个参数(必须按照顺序，否则APP报错：-1)
                String resultCode = wxResponse.get("result_code");
                returnMap.put("appid", wxResponse.get("appid"));
                returnMap.put("noncestr", wxResponse.get("nonce_str"));
                returnMap.put("returnMsg", wxResponse.get("return_msg"));
                returnMap.put("errCodees", wxResponse.get("err_code_des"));
                //resultCode 为SUCCESS，才会返回prepay_id和trade_type
                if ("SUCCESS".equals(resultCode)) {
                    returnMap.put("package","Sign=WXPay");
                    returnMap.put("partnerid", wxResponse.get("mch_id"));
                    returnMap.put("prepayid", wxResponse.get("prepay_id"));
                    //单位为秒
                    returnMap.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
                    //签名
                    returnMap.put("sign",sign);
                    //获取预支付交易回话标志
                    returnMap.put("trade_type", wxResponse.get("trade_type"));
                    return ResponseResult.success(returnMap);
                } else {
                    //此时返回没有预付订单的数据
                    return ResponseResult.success(returnMap);
                }
            } else {
                return ResponseResult.success(returnMap);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseResult.fail(BizCodeEnume.SYSTEM_ERROR.getCode(),BizCodeEnume.SYSTEM_ERROR.getMsg());
    }
}
